// -----------------------------------------------------------
// Game Framework
// Copyright © 2024-2024 deadcycle. All rights reserved.
// Homepage: https://deadcycle.gitee.io
// Feedback: deadcycle@163.com
// -----------------------------------------------------------

using UnityEngine;

namespace UIWidget
{
    /// <summary>
    /// 坐标系相关算法。
    /// </summary>
    public static class Coordinate
    {
        private static readonly Vector3[] s_WorldCorners = new Vector3[4];

        /// <summary>
        /// 将rectTransform在画布上的位置转换为屏幕坐标系中的位置。
        /// </summary>
        public static Vector2 RectTransformToScreenPoint(Canvas canvas, RectTransform transform)
        {
            if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)
            {
                // 画面渲染模式为屏幕空间叠加 (UI渲染直接叠加在屏幕上)
                Vector2 size = Vector2.Scale(transform.rect.size, transform.lossyScale);
                Rect rect = new Rect(transform.position.x, transform.position.y, size.x, size.y);
                rect.x -= transform.pivot.x * size.x;
                rect.y = rect.y - (1.0f - transform.pivot.y) * size.y + rect.height;

                return rect.center;
            }

            // 其他的渲染模式, 使用世界相机进行转换
            Camera camera = canvas.worldCamera ?? Camera.main;

            if (!camera)
            {
                return Vector2.zero;
            }

            transform.GetWorldCorners(s_WorldCorners);

            return RectTransformUtility.WorldToScreenPoint(camera,
                (s_WorldCorners[0] + s_WorldCorners[2]) / 2);
        }

        /// <summary>
        /// 极坐标系坐标->笛卡尔坐标系坐标
        /// </summary>
        /// <param name="radius">半径</param>
        /// <param name="angleDegrees">角度</param>
        /// <param name="x">输出参数x</param>
        /// <param name="y">输出参数y</param>
        public static void PolarToCartesian(float radius, float angleDegrees, out float x,
            out float y)
        {
            // 将角度转换为弧度
            float angleRadians = angleDegrees * Mathf.Deg2Rad;

            // 计算笛卡尔坐标
            x = radius * Mathf.Sin(angleRadians);
            y = radius * Mathf.Cos(angleRadians);
        }
    }
}